/****************************************************************************
*   sapi.idl
*
*   This is the interface definition file for the Microsoft Speech API
*   Version 5.0.
*
*   Copyright (c) Microsoft Corporation. All rights reserved.
*****************************************************************************/

//--- SAPI 5 requires the Platform SDK to define things like DWORD_PTR
cpp_quote("#ifndef MAXULONG_PTR")
cpp_quote("#error SAPI 5 requires a newer version of the Platform SDK than you have installed.")
cpp_quote("#endif // MAXULONG_PTR")
cpp_quote("")

//--- Compiler Directive ----------------------------------------------------
cpp_quote("#pragma warning(disable:4201) // Allow nameless structs/unions")

//--- Includes --------------------------------------------------------------
import "oaidl.idl";
import "ocidl.idl";

//--- Locally scoped define for LANGID
#ifndef LANGID
#define LANGID WORD
#endif

//--- Link with sapi.lib
cpp_quote("#pragma comment(lib, \"sapi.lib\")")

//--- Forward and External Declarations -------------------------------------

cpp_quote("#if 0")  // Ignore our definition in the .H file
typedef [restricted] struct WAVEFORMATEX
{
    WORD    wFormatTag;        /* format type */
    WORD    nChannels;         /* number of channels (i.e. mono, stereo...) */
    DWORD   nSamplesPerSec;    /* sample rate */
    DWORD   nAvgBytesPerSec;   /* for buffer estimation */
    WORD    nBlockAlign;       /* block size of data */
    WORD    wBitsPerSample;    /* Number of bits per sample of mono data */
    WORD    cbSize;            /* The count in bytes of the size of
                                    extra information (after cbSize) */

} WAVEFORMATEX;
cpp_quote("#else")
cpp_quote("#include <mmsystem.h>")
cpp_quote("#endif")


//--- Notifications
interface ISpNotifySource;
interface ISpNotifySink;
interface ISpNotifyTranslator;

//--- Object tokens
interface ISpDataKey;
interface ISpObjectTokenCategory;
interface ISpObjectToken;
interface IEnumSpObjectTokens;
interface ISpObjectWithToken;

//--- Resource management
interface ISpResourceManager;

//--- Speech specific events
interface ISpEventSource;
interface ISpEventSink;

//--- Audio streams
interface ISpStreamFormat;
interface ISpStream;
interface ISpStreamFormatConverter;
interface ISpAudio;
interface ISpMMSysAudio;
interface ISpTranscript;


//--- TTS interface
interface ISpVoice;

//--- SR interfaces
interface ISpRecoResult;
interface ISpRecoContext;
interface ISpRecognizer;
interface ISpProperties;

//--- Lexicon interfaces
interface ISpLexicon;

//--- Phone Converter
interface ISpPhoneConverter;

//--- Phrase interface
interface ISpPhrase; 

//
//--- Constants -------------------------------------------------------------
//

//--- DataKey locations
typedef enum SPDATAKEYLOCATION
{
    SPDKL_DefaultLocation = 0,
    SPDKL_CurrentUser = 1,
    SPDKL_LocalMachine = 2,
    SPDKL_CurrentConfig = 5
} SPDATAKEYLOCATION;

//--- TokenUI constants
cpp_quote("#define SPDUI_EngineProperties   L\"EngineProperties\"")
cpp_quote("#define SPDUI_AddRemoveWord      L\"AddRemoveWord\"")
cpp_quote("#define SPDUI_UserTraining       L\"UserTraining\"")
cpp_quote("#define SPDUI_MicTraining        L\"MicTraining\"")
cpp_quote("#define SPDUI_RecoProfileProperties L\"RecoProfileProperties\"")
cpp_quote("#define SPDUI_AudioProperties    L\"AudioProperties\"")
cpp_quote("#define SPDUI_AudioVolume        L\"AudioVolume\"")

//--- Data formats - these are used by the CSpStreamFormat class in sphelper.h
typedef enum SPSTREAMFORMAT
{
    SPSF_Default = -1,
    SPSF_NoAssignedFormat = 0,  // Similar to GUID_NULL
    SPSF_Text,
    SPSF_NonStandardFormat,     // Non-SAPI 5.0 standard format with no WAVEFORMATEX description
    SPSF_ExtendedAudioFormat,   // Non-SAPI 5.0 standard format but has WAVEFORMATEX description
    // Standard PCM wave formats
    SPSF_8kHz8BitMono,
    SPSF_8kHz8BitStereo,
    SPSF_8kHz16BitMono,
    SPSF_8kHz16BitStereo,
    SPSF_11kHz8BitMono,
    SPSF_11kHz8BitStereo,
    SPSF_11kHz16BitMono,
    SPSF_11kHz16BitStereo,
    SPSF_12kHz8BitMono,
    SPSF_12kHz8BitStereo,
    SPSF_12kHz16BitMono,
    SPSF_12kHz16BitStereo,
    SPSF_16kHz8BitMono,
    SPSF_16kHz8BitStereo,
    SPSF_16kHz16BitMono,
    SPSF_16kHz16BitStereo,
    SPSF_22kHz8BitMono,
    SPSF_22kHz8BitStereo,
    SPSF_22kHz16BitMono,
    SPSF_22kHz16BitStereo,
    SPSF_24kHz8BitMono,
    SPSF_24kHz8BitStereo,
    SPSF_24kHz16BitMono,
    SPSF_24kHz16BitStereo,
    SPSF_32kHz8BitMono,
    SPSF_32kHz8BitStereo,
    SPSF_32kHz16BitMono,
    SPSF_32kHz16BitStereo,
    SPSF_44kHz8BitMono,
    SPSF_44kHz8BitStereo,
    SPSF_44kHz16BitMono,
    SPSF_44kHz16BitStereo,
    SPSF_48kHz8BitMono,
    SPSF_48kHz8BitStereo,
    SPSF_48kHz16BitMono,
    SPSF_48kHz16BitStereo,
    // TrueSpeech format
    SPSF_TrueSpeech_8kHz1BitMono,
    // A-Law formats
    SPSF_CCITT_ALaw_8kHzMono,
    SPSF_CCITT_ALaw_8kHzStereo,
    SPSF_CCITT_ALaw_11kHzMono,
    SPSF_CCITT_ALaw_11kHzStereo,
    SPSF_CCITT_ALaw_22kHzMono,
    SPSF_CCITT_ALaw_22kHzStereo,
    SPSF_CCITT_ALaw_44kHzMono,
    SPSF_CCITT_ALaw_44kHzStereo,
    // u-Law formats
    SPSF_CCITT_uLaw_8kHzMono,
    SPSF_CCITT_uLaw_8kHzStereo,
    SPSF_CCITT_uLaw_11kHzMono,
    SPSF_CCITT_uLaw_11kHzStereo,
    SPSF_CCITT_uLaw_22kHzMono,
    SPSF_CCITT_uLaw_22kHzStereo,
    SPSF_CCITT_uLaw_44kHzMono,
    SPSF_CCITT_uLaw_44kHzStereo,
    // ADPCM formats
    SPSF_ADPCM_8kHzMono,
    SPSF_ADPCM_8kHzStereo,
    SPSF_ADPCM_11kHzMono,
    SPSF_ADPCM_11kHzStereo,
    SPSF_ADPCM_22kHzMono,
    SPSF_ADPCM_22kHzStereo,
    SPSF_ADPCM_44kHzMono,
    SPSF_ADPCM_44kHzStereo,
    // GSM 6.10 formats
    SPSF_GSM610_8kHzMono,
    SPSF_GSM610_11kHzMono,
    SPSF_GSM610_22kHzMono,
    SPSF_GSM610_44kHzMono,
    SPSF_NUM_FORMATS
} SPSTREAMFORMAT;

cpp_quote("EXTERN_C const GUID SPDFID_Text;")
cpp_quote("EXTERN_C const GUID SPDFID_WaveFormatEx;")

//--- Root of registry entries for speech use
cpp_quote("#define SPREG_USER_ROOT          L\"HKEY_CURRENT_USER\\\\SOFTWARE\\\\Microsoft\\\\Speech\"")
cpp_quote("#define SPREG_LOCAL_MACHINE_ROOT L\"HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Speech\"")

//--- Categories for speech resource management
cpp_quote("#define SPCAT_AUDIOOUT         L\"HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Speech\\\\AudioOutput\"")
cpp_quote("#define SPCAT_AUDIOIN          L\"HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Speech\\\\AudioInput\"")
cpp_quote("#define SPCAT_VOICES           L\"HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Speech\\\\Voices\"")
cpp_quote("#define SPCAT_RECOGNIZERS      L\"HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Speech\\\\Recognizers\"")
cpp_quote("#define SPCAT_APPLEXICONS      L\"HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Speech\\\\AppLexicons\"")
cpp_quote("#define SPCAT_PHONECONVERTERS  L\"HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Speech\\\\PhoneConverters\"")
cpp_quote("#define SPCAT_RECOPROFILES     L\"HKEY_CURRENT_USER\\\\SOFTWARE\\\\Microsoft\\\\Speech\\\\RecoProfiles\"")

//--- Specific token ids of interest
cpp_quote("#define SPMMSYS_AUDIO_IN_TOKEN_ID        L\"HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Speech\\\\AudioInput\\\\TokenEnums\\\\MMAudioIn\\\\\"")
cpp_quote("#define SPMMSYS_AUDIO_OUT_TOKEN_ID       L\"HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Speech\\\\AudioOutput\\\\TokenEnums\\\\MMAudioOut\\\\\"")
cpp_quote("#define SPCURRENT_USER_LEXICON_TOKEN_ID  L\"HKEY_CURRENT_USER\\\\SOFTWARE\\\\Microsoft\\\\Speech\\\\CurrentUserLexicon\"")

//--- Standard token values
cpp_quote("#define SPTOKENVALUE_CLSID L\"CLSID\"")

//--- Standard voice category values
cpp_quote("#define SPVOICECATEGORY_TTSRATE L\"DefaultTTSRate\"")

//--- Standard SR Engine properties
cpp_quote("#define SPPROP_RESOURCE_USAGE              L\"ResourceUsage\"")
cpp_quote("#define SPPROP_HIGH_CONFIDENCE_THRESHOLD   L\"HighConfidenceThreshold\"")
cpp_quote("#define SPPROP_NORMAL_CONFIDENCE_THRESHOLD L\"NormalConfidenceThreshold\"")
cpp_quote("#define SPPROP_LOW_CONFIDENCE_THRESHOLD    L\"LowConfidenceThreshold\"")
cpp_quote("#define SPPROP_RESPONSE_SPEED              L\"ResponseSpeed\"")
cpp_quote("#define SPPROP_COMPLEX_RESPONSE_SPEED      L\"ComplexResponseSpeed\"")
cpp_quote("#define SPPROP_ADAPTATION_ON               L\"AdaptationOn\"")

//--- Standard SAPI Recognition Topics
cpp_quote("#define SPTOPIC_SPELLING L\"Spelling\"")

// CFG Wildcard token
cpp_quote("#define SPWILDCARD L\"...\"")

// CFG Dication token
cpp_quote("#define SPDICTATION    L\"*\"")
cpp_quote("#define SPINFDICTATION L\"*+\"")

// CFG confidence scores
const signed char SP_LOW_CONFIDENCE = -1;
const signed char SP_NORMAL_CONFIDENCE = 0;
const signed char SP_HIGH_CONFIDENCE = +1;

// CFG default weight
const float DEFAULT_WEIGHT = 1.0;

// Lexicon word and pronunciation limits
const ULONG SP_MAX_WORD_LENGTH = 128;
const ULONG SP_MAX_PRON_LENGTH = 384;

//
//--- Interface definitions -------------------------------------------------
//

//--- ISpNotifyCallback -----------------------------------------------------

cpp_quote("#if defined(__cplusplus)")
cpp_quote("interface ISpNotifyCallback")
cpp_quote("{")
cpp_quote("virtual HRESULT STDMETHODCALLTYPE NotifyCallback(")
cpp_quote("                                     WPARAM wParam,")
cpp_quote("                                     LPARAM lParam) = 0;")
cpp_quote("};")
cpp_quote("#else")
typedef void * ISpNotifyCallback;
cpp_quote("#endif")

cpp_quote("#if 0")
typedef void * SPNOTIFYCALLBACK;
cpp_quote("#else")
cpp_quote("typedef void __stdcall SPNOTIFYCALLBACK(WPARAM wParam, LPARAM lParam);")
cpp_quote("#endif")

//--- ISpNotifySource -------------------------------------------------------
[
    object,
    uuid(5EFF4AEF-8487-11D2-961C-00C04F8EE628),
    helpstring("ISpNotifySource Interface"),
    pointer_default(unique),
    restricted
]
interface ISpNotifySource : IUnknown
{
    HRESULT SetNotifySink([in] ISpNotifySink * pNotifySink);
    [local] HRESULT SetNotifyWindowMessage(
                [in] HWND hWnd, 
                [in] UINT Msg, 
                [in] WPARAM wParam, 
                [in] LPARAM lParam);
    [local] HRESULT SetNotifyCallbackFunction(
                [in] SPNOTIFYCALLBACK * pfnCallback, 
                [in] WPARAM wParam, 
                [in] LPARAM lParam);
    [local] HRESULT SetNotifyCallbackInterface(
                [in] ISpNotifyCallback * pSpCallback, 
                [in] WPARAM wParam, 
                [in] LPARAM lParam);
    [local] HRESULT SetNotifyWin32Event(void);
    [local] HRESULT WaitForNotifyEvent([in] DWORD dwMilliseconds);
    [local] HANDLE  GetNotifyEventHandle();
}

//--- ISpNotifySink ---------------------------------------------------------
[
    object,
    uuid(259684DC-37C3-11D2-9603-00C04F8EE628),
    helpstring("ISpNotifySink Interface"),
    pointer_default(unique),
    restricted
]
interface ISpNotifySink : IUnknown
{
    HRESULT Notify(void);
}


//--- ISpNotifyTranslator ---------------------------------------------------
[
    object,
    uuid(ACA16614-5D3D-11D2-960E-00C04F8EE628),
    helpstring("ISpNotifyTranslator Interface"),
    pointer_default(unique),
    local,
    restricted
]
interface ISpNotifyTranslator : ISpNotifySink
{
    HRESULT InitWindowMessage(
                [in] HWND hWnd, 
                [in] UINT Msg, 
                [in] WPARAM wParam, 
                [in] LPARAM lParam);
    HRESULT InitCallback(
                [in] SPNOTIFYCALLBACK * pfnCallback, 
                [in] WPARAM wParam, 
                [in] LPARAM lParam);
    HRESULT InitSpNotifyCallback(
                [in] ISpNotifyCallback * pSpCallback, 
                [in] WPARAM wParam, 
                [in] LPARAM lParam);

    HRESULT InitWin32Event(
                HANDLE hEvent, 
                BOOL fCloseHandleOnRelease);
    HRESULT Wait([in] DWORD dwMilliseconds);
    HANDLE  GetEventHandle();
}


//--- ISpDataKey ------------------------------------------------------------
[
    object,
    uuid(14056581-E16C-11D2-BB90-00C04F8EE6C0),
    helpstring("ISpDataKey Interface"),
    pointer_default(unique),
    restricted
]
interface ISpDataKey : IUnknown
{
    HRESULT SetData( const WCHAR * pszValueName, ULONG cbData, const BYTE * pData);
    HRESULT GetData( const WCHAR * pszValueName, ULONG * pcbData, BYTE * pData);
    HRESULT SetStringValue( const WCHAR * pszValueName, const WCHAR * pszValue );
    HRESULT GetStringValue( const WCHAR * pszValueName, WCHAR ** ppszValue);
    HRESULT SetDWORD(const WCHAR * pszKeyName, DWORD dwValue );
    HRESULT GetDWORD(const WCHAR * pszKeyName, DWORD *pdwValue );
    HRESULT OpenKey(const WCHAR * pszSubKeyName, ISpDataKey ** ppSubKey);
    HRESULT CreateKey(const WCHAR * pszSubKey, ISpDataKey ** ppSubKey);
    HRESULT DeleteKey(const WCHAR * pszSubKey);
    HRESULT DeleteValue(const WCHAR * pszValueName);
    HRESULT EnumKeys(ULONG Index, WCHAR ** ppszSubKeyName);
    HRESULT EnumValues(ULONG Index, WCHAR ** ppszValueName);
};

//--- ISpRegDataKey ---------------------------------------------------------
[
    object,
    uuid(92A66E2B-C830-4149-83DF-6FC2BA1E7A5B),
    helpstring("ISpRegDataKey"),
    pointer_default(unique),
    restricted
]
interface ISpRegDataKey : ISpDataKey
{
    [local] HRESULT SetKey([in] HKEY hkey, [in] BOOL fReadOnly);
}

//--- ISpObjectTokenCategory ------------------------------------------------
[
    object,
    uuid(2D3D3845-39AF-4850-BBF9-40B49780011D),
    helpstring("ISpObjectTokenCategory"),
    pointer_default(unique),
    restricted
]
interface ISpObjectTokenCategory : ISpDataKey
{
    HRESULT SetId([in] const WCHAR * pszCategoryId, BOOL fCreateIfNotExist);
    HRESULT GetId([out] WCHAR ** ppszCoMemCategoryId);
    HRESULT GetDataKey(SPDATAKEYLOCATION spdkl, ISpDataKey ** ppDataKey);

    HRESULT EnumTokens(
                [in, string] const WCHAR * pzsReqAttribs, 
                [in, string] const WCHAR * pszOptAttribs, 
                [out] IEnumSpObjectTokens ** ppEnum);

    HRESULT SetDefaultTokenId([in] const WCHAR * pszTokenId);
    HRESULT GetDefaultTokenId([out] WCHAR ** ppszCoMemTokenId);
};

//--- ISpObjectToken --------------------------------------------------------
[
    object,
    uuid(14056589-E16C-11D2-BB90-00C04F8EE6C0),
    helpstring("ISpObjectToken Interface"),
    pointer_default(unique),
    restricted
]
interface ISpObjectToken : ISpDataKey
{
    HRESULT SetId(const WCHAR * pszCategoryId, const WCHAR * pszTokenId, BOOL fCreateIfNotExist);
    HRESULT GetId(WCHAR ** ppszCoMemTokenId);
    HRESULT GetCategory(ISpObjectTokenCategory ** ppTokenCategory);

    HRESULT CreateInstance(
                [in] IUnknown * pUnkOuter, 
                [in] DWORD dwClsContext,
                [in] REFIID riid, 
                [out, iid_is(riid)] void ** ppvObject);

    HRESULT GetStorageFileName(
                [in] REFCLSID clsidCaller,
                [in] const WCHAR * pszValueName,
                [in] const WCHAR * pszFileNameSpecifier,
                [in] ULONG nFolder,       // Same as SHGetFolderPath -- If non-zero, must set CSIDL_FLAG_CREATE
                [out] WCHAR ** ppszFilePath);
    HRESULT RemoveStorageFileName(
                [in] REFCLSID clsidCaller,
                [in] const WCHAR * pszKeyName,
                [in] BOOL fDeleteFile);

    HRESULT Remove(const CLSID * pclsidCaller);
    
    [local] HRESULT IsUISupported(
                [in] const WCHAR * pszTypeOfUI,
                [in] void * pvExtraData,
                [in] ULONG cbExtraData,
                [in] IUnknown * punkObject,
                [out] BOOL *pfSupported);
    [local] HRESULT DisplayUI(
                [in] HWND hwndParent,
                [in] const WCHAR * pszTitle,
                [in] const WCHAR * pszTypeOfUI,
                [in] void * pvExtraData,
                [in] ULONG cbExtraData,
                [in] IUnknown * punkObject);
    HRESULT MatchesAttributes(
                [in] const WCHAR * pszAttributes, 
                [out] BOOL *pfMatches);
};

[
    object,
    uuid(B8AAB0CF-346F-49D8-9499-C8B03F161D51),
    helpstring("ISpObjectTokenInit Interface"),
    pointer_default(unique),
    restricted
]
interface ISpObjectTokenInit : ISpObjectToken
{
    HRESULT InitFromDataKey(
                [in] const WCHAR * pszCategoryId, 
                [in] const WCHAR * pszTokenId, 
                [in] ISpDataKey * pDataKey);
};

//--- IEnumSpObjectTokens ---------------------------------------------------
// This interface is used to enumerate speech object tokens

[
    object,
    uuid(06B64F9E-7FDA-11D2-B4F2-00C04F797396),
    helpstring("IEnumSpObjectTokens Interface"),
    pointer_default(unique),
    restricted
]
interface IEnumSpObjectTokens : IUnknown
{
    HRESULT Next([in] ULONG celt,
                 [out, size_is(celt), length_is(*pceltFetched)] ISpObjectToken ** pelt,
                 [out] ULONG *pceltFetched);
    HRESULT Skip([in] ULONG celt);
    
    HRESULT Reset(void);
    HRESULT Clone([out] IEnumSpObjectTokens **ppEnum);
    
    HRESULT Item([in] ULONG Index, [out] ISpObjectToken ** ppToken);
    
    HRESULT GetCount([out] ULONG* pCount);
};

//--- ISpObjectWithToken ----------------------------------------------------
[
    object,
    uuid(5B559F40-E952-11D2-BB91-00C04F8EE6C0),
    helpstring("ISpObjectWithToken Interface"),
    pointer_default(unique),
    restricted
]
interface ISpObjectWithToken : IUnknown
{
    HRESULT SetObjectToken(ISpObjectToken * pToken);
    HRESULT GetObjectToken(ISpObjectToken ** ppToken);
};

//--- ISpResourceManager ----------------------------------------------------
[
    object,
    uuid(93384E18-5014-43D5-ADBB-A78E055926BD),
    helpstring("ISpResourceManager Interface"),
    pointer_default(unique),
    restricted
]
#ifdef _WIN32_WCE
interface ISpResourceManager : IUnknown //IServiceProvider
#else
interface ISpResourceManager : IServiceProvider
#endif // _WIN32_WCE
{
    HRESULT SetObject(
                [in] REFGUID guidServiceId, 
                [in] IUnknown *pUnkObject);
    HRESULT GetObject(
                [in] REFGUID guidServiceId, 
                [in] REFCLSID ObjectCLSID, 
                [in] REFIID ObjectIID,
                [in] BOOL fReleaseWhenLastExternalRefReleased,
                [out, iid_is(ObjectIID)] void** ppObject);
};

//--- ISpEventSource --------------------------------------------------------
typedef enum SPEVENTLPARAMTYPE
{
    SPET_LPARAM_IS_UNDEFINED = 0,
    SPET_LPARAM_IS_TOKEN,
    SPET_LPARAM_IS_OBJECT,
    SPET_LPARAM_IS_POINTER,
    SPET_LPARAM_IS_STRING,
} SPEVENTLPARAMTYPE;

typedef enum SPEVENTENUM
{
    SPEI_UNDEFINED           = 0,

    //--- TTS engine
    SPEI_START_INPUT_STREAM  = 1,
    SPEI_END_INPUT_STREAM    = 2,
    SPEI_VOICE_CHANGE        = 3,   // LPARAM_IS_TOKEN
    SPEI_TTS_BOOKMARK        = 4,   // LPARAM_IS_STRING
    SPEI_WORD_BOUNDARY       = 5,
    SPEI_PHONEME             = 6,
    SPEI_SENTENCE_BOUNDARY   = 7,
    SPEI_VISEME              = 8,
    SPEI_TTS_AUDIO_LEVEL     = 9,   // wParam contains current output audio level

    //--- Engine vendors use these reserved bits
    SPEI_TTS_PRIVATE         = 15,

    SPEI_MIN_TTS             = 1,
    SPEI_MAX_TTS             = 15,

    //--- Speech Recognition
    SPEI_END_SR_STREAM       = 34,      // LPARAM contains HRESULT, WPARAM contains flags (SPESF_xxx)
    SPEI_SOUND_START         = 35,
    SPEI_SOUND_END           = 36,
    SPEI_PHRASE_START        = 37,
    SPEI_RECOGNITION         = 38,
    SPEI_HYPOTHESIS          = 39,
    SPEI_SR_BOOKMARK         = 40,
    SPEI_PROPERTY_NUM_CHANGE   = 41,  // LPARAM points to a string, WPARAM is the attrib value
    SPEI_PROPERTY_STRING_CHANGE= 42,  // LPARAM pointer to buffer.  Two concatinated null terminated strings.
    SPEI_FALSE_RECOGNITION   = 43,  // apparent speech with no valid recognition
    SPEI_INTERFERENCE        = 44,  // LPARAM is any combination of SPINTERFERENCE flags
    SPEI_REQUEST_UI          = 45,  // LPARAM is string.  
    SPEI_RECO_STATE_CHANGE   = 46,  // wParam contains new reco state
    SPEI_ADAPTATION          = 47,  // we are now ready to accept the adaptation buffer
    SPEI_START_SR_STREAM     = 48,
    SPEI_RECO_OTHER_CONTEXT  = 49,  // Phrase finished and recognized, but for other context
    SPEI_SR_AUDIO_LEVEL      = 50,  // wParam contains current input audio level

    //--- Engine vendors use these reserved bits
    SPEI_SR_PRIVATE          = 52,

    SPEI_MIN_SR              = 34,
    SPEI_MAX_SR              = 52,

    SPEI_RESERVED1           = 30,  // do not use
    SPEI_RESERVED2           = 33,  // do not use
    SPEI_RESERVED3           = 63   // do not use
} SPEVENTENUM;

cpp_quote("#define SPFEI_FLAGCHECK ( (1ui64 << SPEI_RESERVED1) | (1ui64 << SPEI_RESERVED2) )")

cpp_quote("#define SPFEI_ALL_TTS_EVENTS (0x000000000000FFFEui64 | SPFEI_FLAGCHECK)")
cpp_quote("#define SPFEI_ALL_SR_EVENTS  (0x001FFFFC00000000ui64 | SPFEI_FLAGCHECK)")
cpp_quote("#define SPFEI_ALL_EVENTS      0xEFFFFFFFFFFFFFFFui64")

// The SPFEI macro converts an SPEVENTENUM event value into a 64-bit value.
// Multiple values can then be OR-ed together and passed to SetInterest.
cpp_quote("#define SPFEI(SPEI_ord) ((1ui64 << SPEI_ord) | SPFEI_FLAGCHECK)")

// SPEVENT is defined 2 ways, because the current version of MIDL does not allow enumerations
// to be used as bit fields.  So we define eEventId and elParamType as int bitfields for MIDL
// and redefine them as their appropriate enumerations for C++
cpp_quote("#if 0")
typedef [restricted] struct SPEVENT
{
    WORD        eEventId;      //SPEVENTENUM
    WORD        elParamType;   //SPEVENTLPARAMTYPE
    ULONG       ulStreamNum;        // Input stream number this event is associated with
    ULONGLONG   ullAudioStreamOffset;
    WPARAM      wParam;
    LPARAM      lParam;
} SPEVENT;

typedef [restricted] struct SPSERIALIZEDEVENT
{
    WORD        eEventId;           //SPEVENTENUM
    WORD        elParamType;        //SPEVENTLPARAMTYPE
    ULONG       ulStreamNum;        // Input stream number this event is associated with
    ULONGLONG   ullAudioStreamOffset;
    ULONG       SerializedwParam;
    LONG        SerializedlParam;
} SPSERIALIZEDEVENT;

typedef [restricted] struct SPSERIALIZEDEVENT64
{
    WORD        eEventId;           //SPEVENTENUM
    WORD        elParamType;        //SPEVENTLPARAMTYPE
    ULONG       ulStreamNum;        // Input stream number this event is associated with
    ULONGLONG   ullAudioStreamOffset;
    ULONGLONG   SerializedwParam;
    LONGLONG    SerializedlParam;
} SPSERIALIZEDEVENT64;

cpp_quote("#else")
cpp_quote("typedef struct SPEVENT")
cpp_quote("{")
cpp_quote("    SPEVENTENUM        eEventId : 16;")
cpp_quote("    SPEVENTLPARAMTYPE  elParamType : 16;")
cpp_quote("    ULONG       ulStreamNum;")
cpp_quote("    ULONGLONG   ullAudioStreamOffset;")
cpp_quote("    WPARAM      wParam;")
cpp_quote("    LPARAM      lParam;")
cpp_quote("} SPEVENT;")
cpp_quote("typedef struct SPSERIALIZEDEVENT")
cpp_quote("{")
cpp_quote("    SPEVENTENUM        eEventId : 16;")
cpp_quote("    SPEVENTLPARAMTYPE  elParamType : 16;")
cpp_quote("    ULONG       ulStreamNum;")
cpp_quote("    ULONGLONG   ullAudioStreamOffset;")
cpp_quote("    ULONG       SerializedwParam;")
cpp_quote("    LONG        SerializedlParam;")
cpp_quote("} SPSERIALIZEDEVENT;")
cpp_quote("typedef struct SPSERIALIZEDEVENT64")
cpp_quote("{")
cpp_quote("    SPEVENTENUM        eEventId : 16;")
cpp_quote("    SPEVENTLPARAMTYPE  elParamType : 16;")
cpp_quote("    ULONG       ulStreamNum;")
cpp_quote("    ULONGLONG   ullAudioStreamOffset;")
cpp_quote("    ULONGLONG   SerializedwParam;")
cpp_quote("    LONGLONG    SerializedlParam;")
cpp_quote("} SPSERIALIZEDEVENT64;")
cpp_quote("#endif")

//--- Types of interference
typedef enum SPINTERFERENCE
{
    SPINTERFERENCE_NONE     = 0,
    SPINTERFERENCE_NOISE,
    SPINTERFERENCE_NOSIGNAL,
    SPINTERFERENCE_TOOLOUD,
    SPINTERFERENCE_TOOQUIET,
    SPINTERFERENCE_TOOFAST,
    SPINTERFERENCE_TOOSLOW
} SPINTERFERENCE;

//--- Flags for END_SR_STREAM event (in WPARAM)
typedef enum SPENDSRSTREAMFLAGS
{
    SPESF_NONE              = 0,
    SPESF_STREAM_RELEASED   = (1 << 0)
} SPENDSRSTREAMFLAGS;

//--- Viseme features
typedef enum SPVFEATURE
{
    SPVFEATURE_STRESSED = (1L << 0),
    SPVFEATURE_EMPHASIS = (1L << 1)
} SPVFEATURE;


//--- Viseme event groups
typedef enum SPVISEMES
{
                        // English examples
                        //------------------
    SP_VISEME_0 = 0,    // Silence
    SP_VISEME_1,        // AE, AX, AH
    SP_VISEME_2,        // AA
    SP_VISEME_3,        // AO
    SP_VISEME_4,        // EY, EH, UH
    SP_VISEME_5,        // ER
    SP_VISEME_6,        // y, IY, IH, IX
    SP_VISEME_7,        // w, UW
    SP_VISEME_8,        // OW
    SP_VISEME_9,        // AW
    SP_VISEME_10,       // OY
    SP_VISEME_11,       // AY
    SP_VISEME_12,       // h
    SP_VISEME_13,       // r
    SP_VISEME_14,       // l
    SP_VISEME_15,       // s, z
    SP_VISEME_16,       // SH, CH, JH, ZH
    SP_VISEME_17,       // TH, DH
    SP_VISEME_18,       // f, v
    SP_VISEME_19,       // d, t, n
    SP_VISEME_20,       // k, g, NG
    SP_VISEME_21,       // p, b, m
} SPVISEMES;

typedef [restricted] struct SPEVENTSOURCEINFO
{
    ULONGLONG   ullEventInterest;
    ULONGLONG   ullQueuedInterest;
    ULONG       ulCount;
} SPEVENTSOURCEINFO;

[
    object,
    uuid(BE7A9CCE-5F9E-11D2-960F-00C04F8EE628),
    helpstring("ISpEventSource Interface"),
    pointer_default(unique),
    local,
    restricted
]
interface ISpEventSource : ISpNotifySource
{
    // It is neccessary to use the SPFEI macro to convert the
    // SPEVENTENUM values into ULONGULONG values.
    HRESULT SetInterest(
                [in] ULONGLONG ullEventInterest, 
                [in] ULONGLONG ullQueuedInterest);
                
    HRESULT GetEvents(
                [in] ULONG ulCount, 
                [out, size_is(ulCount)] SPEVENT* pEventArray,
                [out] ULONG *pulFetched);
                
    HRESULT GetInfo([out] SPEVENTSOURCEINFO * pInfo);
};

//--- ISpEventSink ---------------------------------------------------------
[
    object,
    uuid(BE7A9CC9-5F9E-11D2-960F-00C04F8EE628),
    helpstring("ISpEventSink Interface"),
    pointer_default(unique),
    local,
    restricted
]
interface ISpEventSink : IUnknown
{
    HRESULT AddEvents([in] const SPEVENT* pEventArray, [in] ULONG ulCount);
    HRESULT GetEventInterest([out] ULONGLONG * pullEventInterest);
};


//--- ISpStreamFormat -------------------------------------------------------
[
    object,
    uuid(BED530BE-2606-4F4D-A1C0-54C5CDA5566F),
    helpstring("ISpStreamFormat Interface"),
    pointer_default(unique),
    restricted
]
interface ISpStreamFormat : IStream
{
    HRESULT GetFormat(GUID * pguidFormatId, WAVEFORMATEX ** ppCoMemWaveFormatEx);
}

typedef enum SPFILEMODE
{
    SPFM_OPEN_READONLY,     // Open existing file, read-only
    SPFM_OPEN_READWRITE,    // Open existing file, read-write    
    SPFM_CREATE,            // Open file if exists, else create if does not exist (opens read-write)    
    SPFM_CREATE_ALWAYS,     // Create file even if file exists.  Destroys old file.  (opens read-write)
    SPFM_NUM_MODES          // Used for limit checking
} SPFILEMODE;

//--- ISpStream -------------------------------------------------------------

[
    object,
    uuid(12E3CCA9-7518-44C5-A5E7-BA5A79CB929E),
    helpstring("ISpStream Interface"),
    pointer_default(unique),
    restricted
]
interface ISpStream : ISpStreamFormat
{
    HRESULT SetBaseStream(IStream * pStream, REFGUID rguidFormat, const WAVEFORMATEX * pWaveFormatEx);
    HRESULT GetBaseStream(IStream ** ppStream);
    HRESULT BindToFile(const WCHAR * pszFileName, SPFILEMODE eMode,
                       const GUID * pFormatId, const WAVEFORMATEX * pWaveFormatEx, 
                       ULONGLONG ullEventInterest);
    HRESULT Close();
}

//--- ISpStreamFormatConverter ----------------------------------------------
[
    object,
    uuid(678A932C-EA71-4446-9B41-78FDA6280A29),
    helpstring("ISpStreamFormatConverter Interface"),
    pointer_default(unique),
    restricted
]
interface ISpStreamFormatConverter : ISpStreamFormat
{
    HRESULT SetBaseStream(
                [in] ISpStreamFormat * pStream,
                [in] BOOL fSetFormatToBaseStreamFormat,  // If true, then format of format converter stream
                [in] BOOL fWriteToBaseStream );          // will be set to same format as bass stream
                                                         // (set up as a pass-through).  If pStream == NULL
                                                         // and this is set to TRUE, then format of stream is reset
    HRESULT GetBaseStream([out] ISpStreamFormat **ppStream);

    HRESULT SetFormat([in] REFGUID rguidFormatIdOfConvertedStream, [in] const WAVEFORMATEX * pWaveFormatExOfConvertedStream);
    // Note:  GetFormat method of ISpStreamFormat returns the format of the converted stream.

    HRESULT ResetSeekPosition();

    HRESULT ScaleConvertedToBaseOffset(
                [in] ULONGLONG ullOffsetConvertedStream,
                [out] ULONGLONG * pullOffsetBaseStream);
    
    HRESULT ScaleBaseToConvertedOffset(
                [in] ULONGLONG ullOffsetBaseStream, 
                [out] ULONGLONG * pullOffsetConvertedStream);
};

//--- ISpAudio --------------------------------------------------------------

typedef enum _SPAUDIOSTATE
{
    SPAS_CLOSED,
    SPAS_STOP,
    SPAS_PAUSE,
    SPAS_RUN
} SPAUDIOSTATE;

typedef [restricted] struct SPAUDIOSTATUS
{
    long            cbFreeBuffSpace;
    ULONG           cbNonBlockingIO;
    SPAUDIOSTATE    State;
    ULONGLONG       CurSeekPos;
    ULONGLONG       CurDevicePos;
    DWORD           dwReserved1;
    DWORD           dwReserved2;
} SPAUDIOSTATUS;

typedef [restricted] struct SPAUDIOBUFFERINFO
{
    ULONG           ulMsMinNotification;
    ULONG           ulMsBufferSize;
    ULONG           ulMsEventBias;
} SPAUDIOBUFFERINFO;

[
    object,
    uuid(C05C768F-FAE8-4EC2-8E07-338321C12452),
    helpstring("ISpAudio Interface"),
    pointer_default(unique),
    local,
    restricted
]
interface ISpAudio : ISpStreamFormat
{
    HRESULT SetState([in] SPAUDIOSTATE NewState, [in]ULONGLONG ullReserved );
    HRESULT SetFormat([in] REFGUID rguidFmtId, [in] const WAVEFORMATEX * pWaveFormatEx);
    HRESULT GetStatus([out] SPAUDIOSTATUS * pStatus);
    HRESULT SetBufferInfo([in] const SPAUDIOBUFFERINFO * pBuffInfo);
    HRESULT GetBufferInfo([out] SPAUDIOBUFFERINFO * pBuffInfo);
    HRESULT GetDefaultFormat([out] GUID * pFormatId, [out] WAVEFORMATEX ** ppCoMemWaveFormatEx);
    HANDLE  EventHandle();
	HRESULT GetVolumeLevel([out] ULONG *pLevel);
	HRESULT SetVolumeLevel([in] ULONG Level);
    HRESULT GetBufferNotifySize([out] ULONG *pcbSize);
    HRESULT SetBufferNotifySize([in] ULONG cbSize);
};

//--- ISpMMSysAudio ---------------------------------------------------------
[
    object,
    uuid(15806F6E-1D70-4B48-98E6-3B1A007509AB),
    helpstring("ISpMMSysAudio Interface"),
    pointer_default(unique),
    local,
    restricted
]
interface ISpMMSysAudio : ISpAudio
{
    HRESULT GetDeviceId([out] UINT * puDeviceId);
    HRESULT SetDeviceId([in] UINT uDeviceId);
    HRESULT GetMMHandle(void ** pHandle);
    HRESULT GetLineId([out] UINT *puLineId);
    HRESULT SetLineId([in] UINT uLineId);
};

//--- ISpTranscript ---------------------------------------------------------
[
    object,
    uuid(10F63BCE-201A-11D3-AC70-00C04F8EE6C0),
    helpstring("ISpTranscript Interface"),
    pointer_default(unique),
    restricted
]
interface ISpTranscript : IUnknown
{
    HRESULT GetTranscript([out, string] WCHAR ** ppszTranscript);
    HRESULT AppendTranscript([in, string] const WCHAR * pszTranscript);
};

//--- Structures used by ISpPhrase interface --------------------------------

typedef enum SPDISPLYATTRIBUTES
{
    SPAF_ONE_TRAILING_SPACE     = 0x02,
    SPAF_TWO_TRAILING_SPACES    = 0x04,
    SPAF_CONSUME_LEADING_SPACES = 0x08,
    SPAF_ALL                    = 0x0F
} SPDISPLAYATTRIBUTES;

typedef unsigned short SPPHONEID;

typedef [restricted] struct SPPHRASEELEMENT
{
    ULONG                   ulAudioTimeOffset;
    ULONG                   ulAudioSizeTime;    // In 100ns units
    ULONG                   ulAudioStreamOffset;
    ULONG                   ulAudioSizeBytes;   
    ULONG                   ulRetainedStreamOffset;
    ULONG                   ulRetainedSizeBytes;   
    const WCHAR *           pszDisplayText;
    const WCHAR *           pszLexicalForm;       
    const SPPHONEID *       pszPronunciation;
    BYTE                    bDisplayAttributes;           
    signed char             RequiredConfidence;
    signed char             ActualConfidence;
    BYTE                    Reserved;
    float                   SREngineConfidence;
} SPPHRASEELEMENT;

typedef [restricted] struct SPPHRASERULE SPPHRASERULE;

struct SPPHRASERULE
{
    const WCHAR *           pszName;
    ULONG                   ulId;
    ULONG                   ulFirstElement;
    ULONG                   ulCountOfElements;
    const SPPHRASERULE *    pNextSibling;
    const SPPHRASERULE *    pFirstChild;
    float                   SREngineConfidence;
    signed char             Confidence;
};


typedef [restricted] struct SPPHRASEPROPERTY SPPHRASEPROPERTY;

struct SPPHRASEPROPERTY
{
    const WCHAR *           pszName;     
    ULONG                   ulId;
    const WCHAR *           pszValue;   
    VARIANT                 vValue;     // Will be VT_BOOL, VT_I4, VT_R4, VT_R8, or VT_BYREF (only for dynamic grammars)
    ULONG                   ulFirstElement;
    ULONG                   ulCountOfElements;
    const SPPHRASEPROPERTY* pNextSibling;
    const SPPHRASEPROPERTY* pFirstChild;
    float                   SREngineConfidence;
    signed char             Confidence;
};

typedef [restricted] struct SPPHRASEREPLACEMENT
{
    BYTE                    bDisplayAttributes;
    const WCHAR *           pszReplacementText;
    ULONG                   ulFirstElement;
    ULONG                   ulCountOfElements;
} SPPHRASEREPLACEMENT;

typedef [restricted] struct SPPHRASE
{
    ULONG                   cbSize;     // Size of structure
    LANGID                  LangID;
    WORD                    wReserved;
    ULONGLONG               ullGrammarID;
    ULONGLONG               ftStartTime;
    ULONGLONG               ullAudioStreamPosition;
    ULONG                   ulAudioSizeBytes;
    ULONG                   ulRetainedSizeBytes;
    ULONG                   ulAudioSizeTime;  // In 100ns units
    SPPHRASERULE            Rule;
    const SPPHRASEPROPERTY* pProperties;
    const SPPHRASEELEMENT * pElements;
    ULONG                   cReplacements;
    const SPPHRASEREPLACEMENT * pReplacements;
    GUID                    SREngineID;        
    ULONG                   ulSREnginePrivateDataSize;
    const BYTE            * pSREnginePrivateData;
} SPPHRASE;


//--- Serialized phrase

typedef [restricted] struct SPSERIALIZEDPHRASE
{
    ULONG                   ulSerializedSize;       // Size of structure in bytes
} SPSERIALIZEDPHRASE;



typedef enum SPVALUETYPE
{
    SPDF_PROPERTY               = 0x00000001,
    SPDF_REPLACEMENT            = 0x00000002,
    SPDF_RULE                   = 0x00000004,
    SPDF_DISPLAYTEXT            = 0x00000008,
    SPDF_LEXICALFORM            = 0x00000010,
    SPDF_PRONUNCIATION          = 0x00000020,
    SPDF_AUDIO                  = 0x00000040,
    SPDF_ALTERNATES             = 0x00000080,
    SPDF_ALL                    = 0x000000FF
} SPVALUETYPE;


// Binary grammar public declaration

typedef struct SPBINARYGRAMMAR
{
    ULONG       ulTotalSerializedSize;
} SPBINARYGRAMMAR;

// Possible arguments for methods that take phrase element start and count

typedef enum SPPHRASERNG
{
    SPPR_ALL_ELEMENTS = -1
} SPPHRASERNG;
cpp_quote("#define SP_GETWHOLEPHRASE SPPR_ALL_ELEMENTS")
cpp_quote("#define SPRR_ALL_ELEMENTS SPPR_ALL_ELEMENTS")

cpp_quote("#if 0")
typedef void * SPSTATEHANDLE;
cpp_quote("#else")
cpp_quote("DECLARE_HANDLE(SPSTATEHANDLE);")
cpp_quote("#endif")




typedef enum SPRECOEVENTFLAGS
{
    SPREF_AutoPause     = (1 << 0),
    SPREF_Emulated      = (1 << 1)
} SPRECOECOEVENTFLAGS;



//--- ISpLexicon ------------------------------------------------------------
typedef enum SPPARTOFSPEECH
{
    //--- SAPI5 public POS category values (bits 28-31)
    SPPS_NotOverriden  = -1,
    SPPS_Unknown       = 0,
    SPPS_Noun          = 0x1000,
    SPPS_Verb          = 0x2000,
    SPPS_Modifier      = 0x3000,
    SPPS_Function      = 0x4000,
    SPPS_Interjection  = 0x5000
} SPPARTOFSPEECH;

typedef enum SPLEXICONTYPE
{
   eLEXTYPE_USER        = (1L << 0),
   eLEXTYPE_APP         = (1L << 1),
   eLEXTYPE_RESERVED1   = (1L << 2),
   eLEXTYPE_RESERVED2   = (1L << 3),
   eLEXTYPE_RESERVED3   = (1L << 4),
   eLEXTYPE_RESERVED4   = (1L << 5),
   eLEXTYPE_RESERVED5   = (1L << 6),
   eLEXTYPE_RESERVED6   = (1L << 7),
   eLEXTYPE_RESERVED7   = (1L << 8),
   eLEXTYPE_RESERVED8   = (1L << 9),
   eLEXTYPE_RESERVED9   = (1L << 10),
   eLEXTYPE_RESERVED10  = (1L << 11),
   eLEXTYPE_PRIVATE1    = (1L << 12),
   eLEXTYPE_PRIVATE2    = (1L << 13),
   eLEXTYPE_PRIVATE3    = (1L << 14),
   eLEXTYPE_PRIVATE4    = (1L << 15),
   eLEXTYPE_PRIVATE5    = (1L << 16),
   eLEXTYPE_PRIVATE6    = (1L << 17),
   eLEXTYPE_PRIVATE7    = (1L << 18),
   eLEXTYPE_PRIVATE8    = (1L << 19),
   eLEXTYPE_PRIVATE9    = (1L << 20),
   eLEXTYPE_PRIVATE10   = (1L << 21),
   eLEXTYPE_PRIVATE11   = (1L << 22),
   eLEXTYPE_PRIVATE12   = (1L << 23),
   eLEXTYPE_PRIVATE13   = (1L << 24),
   eLEXTYPE_PRIVATE14   = (1L << 25),
   eLEXTYPE_PRIVATE15   = (1L << 26),
   eLEXTYPE_PRIVATE16   = (1L << 27),
   eLEXTYPE_PRIVATE17   = (1L << 28),
   eLEXTYPE_PRIVATE18   = (1L << 29),
   eLEXTYPE_PRIVATE19   = (1L << 30),
   eLEXTYPE_PRIVATE20   = (1L << 31),
} SPLEXICONTYPE;

typedef enum SPWORDTYPE
{
   eWORDTYPE_ADDED   = (1L << 0),
   eWORDTYPE_DELETED = (1L << 1)
} SPWORDTYPE;

typedef [restricted] struct SPWORDPRONUNCIATION
{
    struct SPWORDPRONUNCIATION  * pNextWordPronunciation;
    SPLEXICONTYPE                eLexiconType;
	LANGID                       LangID;
    WORD                         wReserved;
    SPPARTOFSPEECH               ePartOfSpeech;
    SPPHONEID                    szPronunciation[1];
} SPWORDPRONUNCIATION;

typedef [restricted] struct SPWORDPRONUNCIATIONLIST
{
    ULONG                  ulSize;
    BYTE                   * pvBuffer;
    SPWORDPRONUNCIATION    * pFirstWordPronunciation;
} SPWORDPRONUNCIATIONLIST;

typedef [restricted] struct SPWORD
{
    struct SPWORD          * pNextWord;
    LANGID                 LangID;
    WORD                   wReserved;
    SPWORDTYPE             eWordType;
    WCHAR                  * pszWord;
    SPWORDPRONUNCIATION    * pFirstWordPronunciation;
} SPWORD;

typedef [restricted] struct SPWORDLIST
{
    ULONG                  ulSize;
    BYTE                   * pvBuffer;
    SPWORD                 * pFirstWord;
} SPWORDLIST;

[
	object,
	uuid(DA41A7C2-5383-4DB2-916B-6C1719E3DB58),
	helpstring("ISpLexicon Interface"),
	pointer_default(unique),
    restricted
]
interface ISpLexicon : IUnknown
{
    HRESULT GetPronunciations(
                [in] const WCHAR * pszWord,
                [in] LANGID LangID,
                [in] DWORD dwFlags,
                [in, out] SPWORDPRONUNCIATIONLIST * pWordPronunciationList
                );
    HRESULT AddPronunciation(
                [in] const WCHAR * pszWord,
                [in] LANGID LangID,
                [in] SPPARTOFSPEECH ePartOfSpeech,
                [in] const SPPHONEID * pszPronunciation
                );
    HRESULT RemovePronunciation(
                [in] const WCHAR * pszWord,
                [in] LANGID LangID,
                [in] SPPARTOFSPEECH ePartOfSpeech,
                [in] const SPPHONEID * pszPronunciation
                );
                
    HRESULT GetGeneration(DWORD *pdwGeneration);
    HRESULT GetGenerationChange(
                [in] DWORD dwFlags,
                [in, out] DWORD *pdwGeneration,
                [in, out] SPWORDLIST * pWordList
                );
                
    HRESULT GetWords(
                [in] DWORD dwFlags,
                [in, out] DWORD *pdwGeneration,
                [in, out] DWORD * pdwCookie,
                [in, out] SPWORDLIST *pWordList
                );
};

[
    object,
    uuid(8565572F-C094-41CC-B56E-10BD9C3FF044),

    helpstring("ISpContainerLexicon Interface"),
    pointer_default(unique),
    restricted
]
interface ISpContainerLexicon : ISpLexicon
{
    HRESULT AddLexicon([in] ISpLexicon *pAddLexicon, [in] DWORD dwFlags);
};

//--- ISpPhoneConverter -----------------------------------------------------
[
	object,
	uuid(8445C581-0CAC-4A38-ABFE-9B2CE2826455),
	helpstring("ISpPhoneConverter Interface"),
	pointer_default(unique),
    restricted
]
interface ISpPhoneConverter : ISpObjectWithToken
{
    HRESULT PhoneToId([in] const WCHAR * pszPhone, [out] SPPHONEID * pId);
    HRESULT IdToPhone([in] const SPPHONEID * pId, [out] WCHAR * pszPhone);
};

//--- ISpVoice --------------------------------------------------------------
//  These structures maintain the absolute state of the voice relative to
//  the voice's baseline XML state.
typedef [restricted] struct SPVPITCH
{
    long MiddleAdj;
    long RangeAdj;
} SPVPITCH;

typedef enum SPVACTIONS
{
    SPVA_Speak = 0,
    SPVA_Silence,
    SPVA_Pronounce,
    SPVA_Bookmark,
    SPVA_SpellOut,
    SPVA_Section,
    SPVA_ParseUnknownTag
} SPVACTIONS;

typedef [restricted] struct SPVCONTEXT
{
    LPCWSTR pCategory;
    LPCWSTR pBefore;
    LPCWSTR pAfter;
} SPVCONTEXT;

typedef [restricted] struct SPVSTATE
{
    //--- Action
    SPVACTIONS  eAction;

    //--- Running state values
    LANGID          LangID;
    WORD            wReserved;
    long            EmphAdj;
    long            RateAdj;
    ULONG           Volume;
    SPVPITCH        PitchAdj;
    ULONG           SilenceMSecs;
    SPPHONEID*      pPhoneIds;              // NULL terminated array of phone ids
    SPPARTOFSPEECH  ePartOfSpeech;
    SPVCONTEXT      Context;
} SPVSTATE;

typedef enum SPRUNSTATE
{
    SPRS_DONE        = (1L << 0),           // The voice is done rendering all queued phrases
    SPRS_IS_SPEAKING = (1L << 1)            // The SpVoice currently has the audio queue claimed
} SPRUNSTATE;

typedef enum SPVLIMITS
{
    SPMIN_VOLUME =   0,
    SPMAX_VOLUME = 100,
    SPMIN_RATE   = -10,
    SPMAX_RATE   =  10
} SPVLIMITS;

typedef enum SPVPRIORITY
{
    SPVPRI_NORMAL = 0,
    SPVPRI_ALERT  = (1L << 0),
    SPVPRI_OVER   = (1L << 1)
} SPVPRIORITY;

typedef [restricted] struct SPVOICESTATUS
{
    ULONG       ulCurrentStream;        // Current stream being rendered
    ULONG       ulLastStreamQueued;     // Number of the last stream queued
    HRESULT     hrLastResult;           // Result of last speak
    DWORD       dwRunningState;         // SPRUNSTATE
    ULONG       ulInputWordPos;         // Input position of current word being rendered
    ULONG       ulInputWordLen;         // Length of current word being rendered
    ULONG       ulInputSentPos;         // Input position of current sentence being rendered
    ULONG       ulInputSentLen;         // Length of current sentence being rendered
    LONG        lBookmarkId;            // Current bookmark converted to a long integer
    SPPHONEID   PhonemeId;              // Current phoneme id
    SPVISEMES   VisemeId;               // Current viseme
    DWORD       dwReserved1;            // Reserved for future expansion
    DWORD       dwReserved2;            // Reserved for future expansion
} SPVOICESTATUS;

typedef enum SPEAKFLAGS
{
    //--- SpVoice flags
    SPF_DEFAULT            = 0,             // Synchronous, no purge, xml auto detect
    SPF_ASYNC              = (1L << 0),     // Asynchronous call
    SPF_PURGEBEFORESPEAK   = (1L << 1),     // Purge current data prior to speaking this
    SPF_IS_FILENAME        = (1L << 2),     // The string passed to Speak() is a file name
    SPF_IS_XML             = (1L << 3),     // The input text will be parsed for XML markup
    SPF_IS_NOT_XML         = (1L << 4),     // The input text will not be parsed for XML markup
    SPF_PERSIST_XML        = (1L << 5),     // Persists XML global state changes

    //--- Normalizer flags
    SPF_NLP_SPEAK_PUNC     = (1L << 6),     // The normalization processor should speak the punctuation

    //--- Masks
    SPF_NLP_MASK           = (SPF_NLP_SPEAK_PUNC),
    SPF_VOICE_MASK         = (SPF_ASYNC|SPF_PURGEBEFORESPEAK|SPF_IS_FILENAME|SPF_IS_XML|SPF_IS_NOT_XML|SPF_NLP_MASK|SPF_PERSIST_XML),
    SPF_UNUSED_FLAGS       = ~(SPF_VOICE_MASK)
} SPEAKFLAGS;

[
    object,
    uuid(6C44DF74-72B9-4992-A1EC-EF996E0422D4),
    helpstring("ISpVoice Interface"),
    pointer_default(unique),
    restricted
]
interface ISpVoice : ISpEventSource
{
    HRESULT SetOutput( [in] IUnknown * pUnkOutput, [in]BOOL fAllowFormatChanges );
    HRESULT GetOutputObjectToken( [out] ISpObjectToken ** ppObjectToken );
    HRESULT GetOutputStream( [out] ISpStreamFormat ** ppStream );

    HRESULT Pause( void );
    HRESULT Resume( void );
                
    HRESULT SetVoice([in] ISpObjectToken *pToken);
    HRESULT GetVoice([out] ISpObjectToken **ppToken);
    
    HRESULT Speak(
                [in, string] const WCHAR* pwcs, 
                [in] DWORD dwFlags, 
                [out] ULONG * pulStreamNumber);
    HRESULT SpeakStream(
                [in] IStream* pStream,  // If not ISpStreamFormat supported then SPDFID_Text assumed
                [in] DWORD dwFlags, 
                [out] ULONG * pulStreamNumber);
                
    HRESULT GetStatus(
                [out] SPVOICESTATUS *pStatus, 
                [out, string] WCHAR ** ppszLastBookmark);

    HRESULT Skip( [in,string]WCHAR* pItemType, [in]long lNumItems, [out]ULONG* pulNumSkipped );
                
    HRESULT SetPriority([in] SPVPRIORITY ePriority );
    HRESULT GetPriority([out] SPVPRIORITY* pePriority );

    HRESULT SetAlertBoundary( [in] SPEVENTENUM eBoundary );
    HRESULT GetAlertBoundary( [out] SPEVENTENUM* peBoundary );

    HRESULT SetRate([in] long RateAdjust );
    HRESULT GetRate([out] long* pRateAdjust);
    
    HRESULT SetVolume([in] USHORT usVolume);
    HRESULT GetVolume([out] USHORT* pusVolume);
    
    HRESULT WaitUntilDone([in] ULONG msTimeout);
    
    HRESULT SetSyncSpeakTimeout([in] ULONG msTimeout);
    HRESULT GetSyncSpeakTimeout([out] ULONG * pmsTimeout);

    [local] HANDLE SpeakCompleteEvent();
    
    [local] HRESULT IsUISupported(
                [in] const WCHAR * pszTypeOfUI,
                [in] void * pvExtraData,
                [in] ULONG cbExtraData,
                [out] BOOL *pfSupported);
    [local] HRESULT DisplayUI(
                [in] HWND hwndParent,
                [in] const WCHAR * pszTitle,
                [in] const WCHAR * pszTypeOfUI,
                [in] void * pvExtraData,
                [in] ULONG cbExtraData);
    
};


//--- ISpPhrase interface ---------------------------------------------------
[
    object,
    uuid(1A5C0354-B621-4b5a-8791-D306ED379E53),
    local,
    helpstring("ISpPhrase Interface"),
    pointer_default(unique),
    restricted
]
interface ISpPhrase : IUnknown
{
    HRESULT GetPhrase([out] SPPHRASE ** ppCoMemPhrase);
    HRESULT GetSerializedPhrase([out] SPSERIALIZEDPHRASE ** ppCoMemPhrase);
    HRESULT GetText([in] ULONG ulStart, [in] ULONG ulCount, [in] BOOL fUseTextReplacements, 
					[out] WCHAR ** ppszCoMemText, [out] BYTE * pbDisplayAttributes);
    HRESULT Discard([in] DWORD dwValueTypes);
};

[
    object,
    uuid(8FCEBC98-4E49-4067-9C6C-D86A0E092E3D),
    local,
    helpstring("ISpPhraseAlt Interface"),
    pointer_default(unique),
    restricted
]
interface ISpPhraseAlt : ISpPhrase
{
    HRESULT GetAltInfo(ISpPhrase **ppParent, ULONG *pulStartElementInParent, ULONG *pcElementsInParent,
                        ULONG *pcElementsInAlt);
    HRESULT Commit();
};



//--- ISpRecoResult ---------------------------------------------------------
typedef [restricted] struct SPRECORESULTTIMES
{
    FILETIME        ftStreamTime;           // GetSystemTimeAsFileTime() at start of result
                                            //   UTC time as number of 100-nanosecond intervals
                                            //   since January 1, 1601
    ULONGLONG       ullLength;              // length in 100ns units
    DWORD           dwTickCount;            // GetTickCount() at start of result
                                            //	 milliseconds that have elapsed since the
                                            //   system was started.
    ULONGLONG       ullStart;               // 100ns units since start of stream
} SPRECORESULTTIMES;


typedef struct SPSERIALIZEDRESULT
{
    ULONG           ulSerializedSize;       // Count in bytes (including this ULONG) of the entire phrase
} SPSERIALIZEDRESULT;


[
    object,
    uuid(20B053BE-E235-43cd-9A2A-8D17A48B7842),
    helpstring("ISpRecoResult Interface"),
    pointer_default(unique),
    local,
    restricted
]
interface ISpRecoResult : ISpPhrase
{
    HRESULT GetResultTimes([out] SPRECORESULTTIMES *pTimes);

    HRESULT GetAlternates(
                [in] ULONG ulStartElement,
                [in] ULONG cElements,
                [in] ULONG ulRequestCount,
                [out] ISpPhraseAlt **ppPhrases,
                [out] ULONG *pcPhrasesReturned);

    HRESULT GetAudio(
                [in] ULONG ulStartElement,
                [in] ULONG cElements,
                [out] ISpStreamFormat **ppStream);
    HRESULT SpeakAudio(
                [in] ULONG ulStartElement,
                [in] ULONG cElements,
                [in] DWORD dwFlags, 
                [out] ULONG * pulStreamNumber);

    HRESULT Serialize([out] SPSERIALIZEDRESULT ** ppCoMemSerializedResult);

    HRESULT ScaleAudio([in] const GUID * pAudioFormatId, [in] const WAVEFORMATEX *pWaveFormatEx);

    HRESULT GetRecoContext([out] ISpRecoContext ** ppRecoContext);
};



typedef struct tagSPTEXTSELECTIONINFO
{
    ULONG       ulStartActiveOffset;
    ULONG       cchActiveChars;
    ULONG       ulStartSelection;
    ULONG       cchSelection;
} SPTEXTSELECTIONINFO;


typedef enum SPWORDPRONOUNCEABLE
{
    SPWP_UNKNOWN_WORD_UNPRONOUNCEABLE   = 0,
    SPWP_UNKNOWN_WORD_PRONOUNCEABLE     = 1,
    SPWP_KNOWN_WORD_PRONOUNCEABLE       = 2
} SPWORDPRONOUNCEABLE;


typedef enum SPGRAMMARSTATE
{
    SPGS_DISABLED   = 0,
    SPGS_ENABLED    = 1,
    SPGS_EXCLUSIVE  = 3
} SPGRAMMARSTATE;


typedef enum SPCONTEXTSTATE
{
    SPCS_DISABLED   = 0,
    SPCS_ENABLED    = 1,
} SPCONTEXTSTATE;


typedef enum SPRULESTATE
{
    SPRS_INACTIVE = 0,
    SPRS_ACTIVE = 1,
    SPRS_ACTIVE_WITH_AUTO_PAUSE = 3
} SPRULESTATE;

const ULONGLONG SP_STREAMPOS_ASAP = 0;
const ULONGLONG SP_STREAMPOS_REALTIME = -1;



// Special transition types used only by AddRuleTransition

cpp_quote("#define SPRULETRANS_TEXTBUFFER (SPSTATEHANDLE)(-1)")
cpp_quote("#define SPRULETRANS_WILDCARD   (SPSTATEHANDLE)(-2)")
cpp_quote("#define SPRULETRANS_DICTATION  (SPSTATEHANDLE)(-3)")


typedef enum SPGRAMMARWORDTYPE
{
    SPWT_DISPLAY,
    SPWT_LEXICAL,
    SPWT_PRONUNCIATION
} SPGRAMMARWORDTYPE;

typedef struct tagSPPROPERTYINFO
{
    const WCHAR *           pszName;     
    ULONG                   ulId;
    const WCHAR *           pszValue;
    VARIANT                 vValue;     // Must be VT_BOOL, VT_I4, VT_R4, VT_R8, or VT_BYREF (only for dynamic grammars)
} SPPROPERTYINFO;

typedef enum SPCFGRULEATTRIBUTES
{
    SPRAF_TopLevel      = (1 << 0),
    SPRAF_Active        = (1 << 1),
    SPRAF_Export        = (1 << 2),
    SPRAF_Import        = (1 << 3),
    SPRAF_Interpreter   = (1 << 4),
    SPRAF_Dynamic       = (1 << 5),
    // The following flag is only valid at run-time as part of a rule state and
    // is not valid to pass as part of a rule definition.
    SPRAF_AutoPause     = (1 << 16)
} SPCFGRULEATTRIBUTES;


[
    object,
    uuid(8137828F-591A-4A42-BE58-49EA7EBAAC68),
    helpstring("ISpGrammarBuilder Interface"),
    pointer_default(unique),
    restricted,
    local
]
interface ISpGrammarBuilder : IUnknown
{
    HRESULT ResetGrammar([in] LANGID NewLanguage);

    HRESULT GetRule([in] const WCHAR * pszRuleName,
                    [in] DWORD dwRuleId,
                    [in] DWORD dwAttributes,
                    [in] BOOL fCreateIfNotExist,
                    [out] SPSTATEHANDLE * phInitialState);
    HRESULT ClearRule(SPSTATEHANDLE hState);

    HRESULT CreateNewState(
                SPSTATEHANDLE hState,   
                SPSTATEHANDLE * phState);

    HRESULT AddWordTransition(
                    SPSTATEHANDLE hFromState,
                    SPSTATEHANDLE hToState,
                    const WCHAR * psz,      // If NULL then epsilon
                    const WCHAR * pszSeperators,    // If NULL then psz points to a single word, else specifies valid seperator characters
                    SPGRAMMARWORDTYPE eWordType,
                    float Weight,
                    const SPPROPERTYINFO * pPropInfo);

    HRESULT AddRuleTransition(
                SPSTATEHANDLE hFromState,
                SPSTATEHANDLE hToState,
                SPSTATEHANDLE hRule,    // Must be the initial state of the rule
                float Weight,
                const SPPROPERTYINFO * pPropInfo);

    HRESULT AddResource([in] SPSTATEHANDLE hRuleState,  // Any state handle in a rule is OK
                        [in] const WCHAR * pszResourceName,
                        [in] const WCHAR * pszResourceValue);

    HRESULT Commit(DWORD dwReserved);
};


// --- Options for Load methods on ISpRecoGrammar
typedef enum SPLOADOPTIONS
{
    SPLO_STATIC     = 0,
    SPLO_DYNAMIC    = 1    
} SPLOADOPTIONS;



//--- ISpRecoGrammar -------------------------------------------------------
[
    object,
    uuid(2177DB29-7F45-47D0-8554-067E91C80502),
    helpstring("ISpRecoGrammar Interface"),
    pointer_default(unique),
    restricted,
    local
]
interface ISpRecoGrammar : ISpGrammarBuilder
{
    HRESULT GetGrammarId([out] ULONGLONG * pullGrammarId);
    HRESULT GetRecoContext([out] ISpRecoContext **ppRecoCtxt);

    // Command and control interfaces
    HRESULT LoadCmdFromFile([in, string] const WCHAR * pszFileName, [in] SPLOADOPTIONS Options);
    HRESULT LoadCmdFromObject([in] REFCLSID rcid, [in, string] const WCHAR * pszGrammarName, [in] SPLOADOPTIONS Options);
    HRESULT LoadCmdFromResource([in] HMODULE hModule,
                                [in, string] const WCHAR * pszResourceName,
                                [in, string] const WCHAR * pszResourceType,
                                [in] WORD wLanguage,
                                [in] SPLOADOPTIONS Options);
    HRESULT LoadCmdFromMemory([in] const SPBINARYGRAMMAR * pGrammar, [in] SPLOADOPTIONS Options);
    HRESULT LoadCmdFromProprietaryGrammar(
                                [in] REFGUID rguidParam,
                                [in, string] const WCHAR * pszStringParam,
                                [in] const void * pvDataPrarm,
                                [in] ULONG cbDataSize,
                                [in] SPLOADOPTIONS Options);
    HRESULT SetRuleState([in, string] const WCHAR * pszName, void * pReserved,
                         [in] SPRULESTATE NewState);
    HRESULT SetRuleIdState([in] ULONG ulRuleId, [in] SPRULESTATE NewState);


    // Dictation / statistical language model
    HRESULT LoadDictation([in, string] const WCHAR * pszTopicName, [in] SPLOADOPTIONS Options);
    HRESULT UnloadDictation();
    HRESULT SetDictationState([in] SPRULESTATE NewState);

    // Word sequence buffer
    HRESULT SetWordSequenceData([in] const WCHAR * pText, [in] ULONG cchText, [in] const SPTEXTSELECTIONINFO * pInfo);
    HRESULT SetTextSelection([in] const SPTEXTSELECTIONINFO * pInfo);

    HRESULT IsPronounceable([in, string] const WCHAR * pszWord, [out] SPWORDPRONOUNCEABLE *pWordPronounceable);

    HRESULT SetGrammarState([in] SPGRAMMARSTATE eGrammarState);

    HRESULT SaveCmd([in] IStream * pStream, [out, optional] WCHAR ** ppszCoMemErrorText);

    HRESULT GetGrammarState([out] SPGRAMMARSTATE * peGrammarState);
};





//--- ISpRecoContext --------------------------------------------------------
typedef [restricted] struct SPRECOCONTEXTSTATUS
{
    SPINTERFERENCE  eInterference;
    WCHAR           szRequestTypeOfUI[255]; // If first byte null, there is no UI request
    DWORD           dwReserved1;
    DWORD           dwReserved2;
} SPRECOCONTEXTSTATUS;

typedef enum SPBOOKMARKOPTIONS
{
    SPBO_NONE  = 0,
    SPBO_PAUSE = 1
} SPBOOKMARKOPTIONS;


typedef enum SPAUDIOOPTIONS
{
    SPAO_NONE           = 0,
    SPAO_RETAIN_AUDIO   = (1 << 0)
} SPAUDIOOPTIONS;

[
    object,
    uuid(F740A62F-7C15-489E-8234-940A33D9272D),
    helpstring("ISpRecoContext Interface"),
    pointer_default(unique),
    local,
    restricted
]
interface ISpRecoContext : ISpEventSource
{
    HRESULT GetRecognizer([out] ISpRecognizer ** ppRecognizer);

    HRESULT CreateGrammar([in] ULONGLONG ullGrammarId, [out] ISpRecoGrammar ** ppGrammar);    

    HRESULT GetStatus([out] SPRECOCONTEXTSTATUS *pStatus);

    HRESULT GetMaxAlternates([in] ULONG * pcAlternates);
    HRESULT SetMaxAlternates([in] ULONG cAlternates);

    HRESULT SetAudioOptions([in] SPAUDIOOPTIONS Options, [in] const GUID *pAudioFormatId, [in] const WAVEFORMATEX *pWaveFormatEx);
    HRESULT GetAudioOptions([in] SPAUDIOOPTIONS * pOptions, [out] GUID *pAudioFormatId, [out] WAVEFORMATEX **ppCoMemWFEX);

    HRESULT DeserializeResult(
                [in] const SPSERIALIZEDRESULT * pSerializedResult,
                [out] ISpRecoResult **ppResult);

    HRESULT Bookmark([in] SPBOOKMARKOPTIONS Options, [in] ULONGLONG ullStreamPosition, [in] LPARAM lparamEvent);

    HRESULT SetAdaptationData([in, string] const WCHAR *pAdaptationData, [in] const ULONG cch);

    HRESULT Pause( DWORD dwReserved );
    HRESULT Resume( DWORD dwReserved );

    HRESULT SetVoice([in] ISpVoice *pVoice, [in] BOOL fAllowFormatChanges);
    HRESULT GetVoice([out] ISpVoice **ppVoice);
    HRESULT SetVoicePurgeEvent([in] ULONGLONG ullEventInterest);
    HRESULT GetVoicePurgeEvent([out] ULONGLONG *pullEventInterest);

    HRESULT SetContextState([in] SPCONTEXTSTATE eContextState);
    HRESULT GetContextState([in] SPCONTEXTSTATE * peContextState);
};


//--- ISpProperties ------------------------------------------------------------
[
    object,
    uuid(5B4FB971-B115-4DE1-AD97-E482E3BF6EE4),
    helpstring("ISpProperties Interface"),
    pointer_default(unique),
    local,
    restricted
]
interface ISpProperties : IUnknown
{
    HRESULT SetPropertyNum( [in]const WCHAR* pName, [in]LONG lValue );
    HRESULT GetPropertyNum( [in]const WCHAR* pName, [out]LONG* plValue );
    HRESULT SetPropertyString( [in]const WCHAR* pName, [in]const WCHAR* pValue );
    HRESULT GetPropertyString( [in]const WCHAR* pName, [out]WCHAR** ppCoMemValue );
};

const ULONG SP_MAX_LANGIDS = 20;        // Engine can support up to 20 languages at once

//--- ISpRecognizer ---------------------------------------------------------
typedef [restricted] struct SPRECOGNIZERSTATUS
{
    SPAUDIOSTATUS   AudioStatus;
    ULONGLONG       ullRecognitionStreamPos;
    ULONG           ulStreamNumber;
    ULONG           ulNumActive;    
    CLSID           clsidEngine;
    ULONG           cLangIDs;
    LANGID          aLangID[SP_MAX_LANGIDS];
    DWORD           dwReserved1;
    DWORD           dwReserved2;
} SPRECOGNIZERSTATUS;

typedef enum SPWAVEFORMATTYPE
{
    SPWF_INPUT,        // WAVEFORMATEX of audio input source
    SPWF_SRENGINE      // WAVEFORMATEX of the audio received by the SR engine
} SPSTREAMFORMATTYPE;

typedef enum SPRECOSTATE
{
    SPRST_INACTIVE,             // Audio deactivated
    SPRST_ACTIVE,               // Audio running only if one or more rules are active
    SPRST_ACTIVE_ALWAYS,        // Audio running regardless of rule state
    SPRST_INACTIVE_WITH_PURGE,  // State will be set to inactive, but all active audio purged
    SPRST_NUM_STATES
} SPRECOSTATE;




[
    object,
    uuid(C2B5F241-DAA0-4507-9E16-5A1EAA2B7A5C),
    helpstring("ISpRecognizer Interface"),
    pointer_default(unique),
    restricted
]
interface ISpRecognizer : ISpProperties
{
    HRESULT SetRecognizer([in] ISpObjectToken * pRecognizer);
    HRESULT GetRecognizer([out] ISpObjectToken **ppRecognizer);
    
    HRESULT SetInput([in] IUnknown * pUnkInput, [in] BOOL fAllowFormatChanges);
    HRESULT GetInputObjectToken( [out] ISpObjectToken ** ppToken);

    HRESULT GetInputStream( [out] ISpStreamFormat ** ppStream);
    HRESULT CreateRecoContext([out] ISpRecoContext ** ppNewCtxt);

    HRESULT GetRecoProfile([out] ISpObjectToken **ppToken);
    HRESULT SetRecoProfile([in] ISpObjectToken *pToken);

    HRESULT IsSharedInstance(void);

    HRESULT GetRecoState([out] SPRECOSTATE *pState);
    HRESULT SetRecoState([in] SPRECOSTATE NewState);

    HRESULT GetStatus([out] SPRECOGNIZERSTATUS * pStatus);
    HRESULT GetFormat([in] SPSTREAMFORMATTYPE WaveFormatType, [out] GUID *pFormatId, [out] WAVEFORMATEX **ppCoMemWFEX);

    [local] HRESULT IsUISupported(
                [in] const WCHAR * pszTypeOfUI,
                [in] void * pvExtraData,
                [in] ULONG cbExtraData,
                [out] BOOL *pfSupported);
    [local] HRESULT DisplayUI(
                [in] HWND hwndParent,
                [in] const WCHAR * pszTitle,
                [in] const WCHAR * pszTypeOfUI,
                [in] void * pvExtraData,
                [in] ULONG cbExtraData);
    HRESULT EmulateRecognition([in] ISpPhrase *pPhrase);
};


//
//=== CoClass definitions =====================================================
//
[
    helpstring("Microsoft Speech Object Library"),
    uuid(C866CA3A-32F7-11D2-9602-00C04F8EE628),
    version(5.0)
]
library SpeechLib
{
    importlib("stdole32.tlb");
    importlib("stdole2.tlb");

    //--- SpNotifyTranslator ------------------------------------------------
    [
        uuid(E2AE5372-5D40-11D2-960E-00C04F8EE628),
        helpstring("SpNotify"),
        restricted
    ]
    coclass SpNotifyTranslator
    {
        interface ISpNotifyTranslator;
    }

    //--- SpObjectTokenCategory ---------------------------------------------
    [
        uuid(A910187F-0C7A-45AC-92CC-59EDAFB77B53),
        helpstring("SpObjectTokenCategory"),
        restricted
    ]
    coclass SpObjectTokenCategory
    {
        interface ISpObjectTokenCategory;
    }
    //--- SpObjectToken ---------------------------------------------
    [
        uuid(EF411752-3736-4CB4-9C8C-8EF4CCB58EFE),
        helpstring("SpObjectToken"),
        restricted
    ]
    coclass SpObjectToken
    {
        interface ISpObjectToken;
    }

    //--- SpResourceManager -------------------------------------------------
    [
        uuid(96749373-3391-11D2-9EE3-00C04F797396),
        helpstring("SpResourceManger")
    ]
    coclass SpResourceManager
    {
        [default] interface ISpResourceManager;
    };

    //--- SpStreamFormatConverter -------------------------------------------
    [
        uuid(7013943A-E2EC-11D2-A086-00C04F8EF9B5),
        helpstring("FormatConverter Class"),
        restricted
    ]
    coclass SpStreamFormatConverter
    {
        [default] interface ISpStreamFormatConverter;
    };

    //--- SpMMAudioEnum -----------------------------------------------------
    [
        uuid(AB1890A0-E91F-11D2-BB91-00C04F8EE6C0),
        helpstring("SpMMAudioEnum Class"),
        restricted
    ]
    coclass SpMMAudioEnum
    {
        interface IEnumSpObjectTokens;
    };

    //--- SpMMAudioIn -------------------------------------------------------
    [
        uuid(CF3D2E50-53F2-11D2-960C-00C04F8EE628),
        helpstring("SpAudioIn Class")
    ]
    coclass SpMMAudioIn
    {
        interface ISpEventSource;
        interface ISpEventSink;
        interface ISpObjectWithToken;
        interface ISpMMSysAudio;
    };

    //--- SpMMAudioOut ------------------------------------------------------
    [
        uuid(A8C680EB-3D32-11D2-9EE7-00C04F797396),
        helpstring("SpAudioOut Class")
    ]
    coclass SpMMAudioOut
    {
        interface ISpEventSource;
        interface ISpEventSink;
        interface ISpObjectWithToken;
        interface ISpMMSysAudio;
    };

    //--- SpRecPlayAudio -------------------------------------------------
    [
        uuid(FEE225FC-7AFD-45E9-95D0-5A318079D911),
        helpstring("SpRecPlayAudio Class"),
        restricted
    ]
    coclass SpRecPlayAudio
    {
        interface ISpObjectWithToken;
        interface ISpAudio;
    };

    //--- SpStream ----------------------------------------------------------
    [
        uuid(715D9C59-4442-11D2-9605-00C04F8EE628),
        helpstring("SpStream Class")
    ]
    coclass SpStream
    {
        interface ISpStream;
    };

    //--- SpVoice -----------------------------------------------------------
    [
        control,
        uuid(96749377-3391-11D2-9EE3-00C04F797396),
        helpstring("SpVoice")
    ]
    coclass SpVoice
    {
        interface ISpVoice;
    };

    //--- SpSharedRecoContext -----------------------------------------------
    [
        uuid(47206204-5ECA-11D2-960F-00C04F8EE628),
        helpstring("Shared Recognition Context Class")
    ]
    coclass SpSharedRecoContext
    {
        interface ISpRecoContext;
    };

    //--- SpInprocRecognizer ------------------------------------------------
    [
        uuid(41B89B6B-9399-11D2-9623-00C04F8EE628),
        helpstring("Inproc Recognizer Class")
    ]
    coclass SpInprocRecognizer
    {
        interface ISpRecognizer;
    };

    //--- SpSharedRecognizer ----------------------------------------------
    [
        uuid(3BEE4890-4FE9-4A37-8C1E-5E7E12791C1F),
        helpstring("Shared Recognizer Class")
    ]
    coclass SpSharedRecognizer
    {
        interface ISpRecognizer;
    };

    //--- SpLexicon ----------------------------------------------------------
    [
        uuid(0655E396-25D0-11D3-9C26-00C04F8EF87C),
        helpstring("SpLexicon Class")
    ]
    coclass SpLexicon
    {
        [default] interface ISpLexicon;
    };

    //--- SpUnCompressedLexicon ---------------------------------------------------
    [
        uuid(C9E37C15-DF92-4727-85D6-72E5EEB6995A),
        helpstring("SpUnCompressedLexicon Class")
    ]
    coclass SpUnCompressedLexicon
    {
        [default] interface ISpLexicon;
        interface ISpObjectWithToken;
    };
    
    //--- SpCompressedLexicon ---------------------------------------------------
    [
        uuid(90903716-2F42-11D3-9C26-00C04F8EF87C),
        helpstring("SpCompressedLexicon Class")
    ]
    coclass SpCompressedLexicon
    {
        [default] interface ISpLexicon;
        interface ISpObjectWithToken;
    };

    //--- SpPhoneConverter ------------------------------------------------
    [
        uuid(9185F743-1143-4C28-86B5-BFF14F20E5C8),
        helpstring("SpPhoneConverter Class"),
        restricted
    ]
    coclass SpPhoneConverter
    {
        [default] interface ISpPhoneConverter;
    };

    //--- SpNullPhoneConverter ------------------------------------------------
    [
        uuid(455F24E9-7396-4A16-9715-7C0FDBE3EFE3),
        helpstring("SpNullPhoneConverter Class"),
        restricted
    ]
    coclass SpNullPhoneConverter
    {
        [default] interface ISpPhoneConverter;
    };

}
